/**
 * Copyright (c) 2010-2011 Pierre Labatut
 *
 * This file is part of Space-Chronicles project.
 *
 * Space-Chronicles is free software: you can redistribute it and/or modify it
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or <http://code.google.com/p/space-chronicles/>.
 */
package space.app.common;

import java.awt.AWTException;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

/**
 *
 * @author Pierre
 */
public class ServerTraySupport implements ServerTray {

    final Image original;
    final TrayIcon trayIcon;
    final MenuItem startItem;
    final MenuItem stopItem;
    final ServerFrame frame;
    boolean inconifyMessage = false;

    public ServerTraySupport(final ServerFrame frame, final Image original) {

        if (frame == null) {
            throw new NullPointerException();
        }

        if (original == null) {
            throw new NullPointerException();
        }

        this.frame = frame;
        this.original = original;

        networkIdle = compose(original, "overlay-idle.png");
        networkOffline = compose(original, "overlay-stop.png");
        networkError = compose(original, "overlay-error.png");
        networkRecieve = compose(original, "overlay-transmit-recieve.png");



        SystemTray tray = SystemTray.getSystemTray();
        final MouseListener mouseListener = new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {                
                if (e.getClickCount() >= 2) {
                    frame.showAction.actionPerformed(null);
                }
            }
        };
        final PopupMenu popup = new PopupMenu();

        final MenuItem showItem = new MenuItem("Show");
        showItem.addActionListener(frame.showAction);


        popup.add(showItem);
        popup.addSeparator();

        startItem = new MenuItem("Start Server");
        startItem.addActionListener(frame.startServerAction);
        popup.add(startItem);

        stopItem = new MenuItem("Stop Server");
        stopItem.addActionListener(frame.stopServerAction);
        stopItem.setEnabled(false);
        popup.add(stopItem);

        popup.addSeparator();

        final MenuItem exitItem = new MenuItem("Exit");
        exitItem.addActionListener(frame.exitAction);
        popup.add(exitItem);

        trayIcon = new TrayIcon(original, frame.getTitle(), popup);
        trayIcon.setImageAutoSize(true);
        trayIcon.addMouseListener(mouseListener);
        try {
            tray.add(trayIcon);
        } catch (AWTException ex) {
            throw new RuntimeException(ex);
        }



    }
    private final Image networkIdle;
    private final Image networkOffline;
    private final Image networkError;
    private final Image networkRecieve;

    private static Image compose(Image original, final String resource) {
        if (original == null) {
            throw new NullPointerException();
        }
        if (resource == null) {
            throw new NullPointerException();
        }
        try {
            final BufferedImage newIcon = new BufferedImage(
                    original.getWidth(null), original.getHeight(null),
                    BufferedImage.TYPE_INT_ARGB);
            final Graphics graphics = newIcon.getGraphics();
            graphics.drawImage(original, 0, 0, null);
            final URL url = ServerTraySupport.class.getResource(resource);
            if (url == null) {
                throw new RuntimeException("Resource " + resource + " not found");
            }
            BufferedImage overlay = ImageIO.read(url);
            graphics.drawImage(overlay, 0, 0, null);
            return newIcon;
        } catch (IOException ex) {
            Logger.getLogger(ServerTraySupport.class.getName()).log(Level.SEVERE, null, ex);
            return original;
        }
    }

    private boolean isFrameVisisble() {
        return ((frame.getState() & JFrame.ICONIFIED) == 0) && frame.isVisible() == true;
    }

    public void onServerStart(String message) {
        trayIcon.setImage(networkIdle);
        final String tooltipIdle = frame.getTitle() + "\nServer Started";

        trayIcon.setToolTip(tooltipIdle);

        if (isFrameVisisble() == false) {
            trayIcon.displayMessage("Server Started",
                    message,
                    TrayIcon.MessageType.INFO);
        }

        startItem.setEnabled(false);
        stopItem.setEnabled(true);
    }

    public void onServerStop(String message) {
        final String tooltipOffline = frame.getTitle() + "\nServer Stopped";
        trayIcon.setImage(networkOffline);
        trayIcon.setToolTip(tooltipOffline);
        if (isFrameVisisble() == false) {
            trayIcon.displayMessage("Server Stopped",
                    message,
                    TrayIcon.MessageType.INFO);
        }

        startItem.setEnabled(true);
        stopItem.setEnabled(false);
    }

    public void onServerCrash(String message) {
        final String tooltipError = frame.getTitle() + "\nServer Crashed";
        trayIcon.setImage(networkError);
        trayIcon.setToolTip(tooltipError);
        if (isFrameVisisble() == false) {
            trayIcon.displayMessage("Server Crashed",
                    message,
                    TrayIcon.MessageType.ERROR);
        }
        startItem.setEnabled(true);
        stopItem.setEnabled(false);
    }

    public void onServerRecieve(String message) {
        trayIcon.setImage(networkRecieve);
    }

    public void onServerRecieved(Object scene) {
        if (isFrameVisisble() == false) {
            frame.showAction.actionPerformed(null);
        }
    }

    public void onServerStatus(String text) {
        if (isFrameVisisble() == false) {
            trayIcon.displayMessage("Server Info",
                    text,
                    TrayIcon.MessageType.INFO);
        }
    }

    public void onFrameIconify() {
        frame.setVisible(false);
        if (inconifyMessage == false) {
            inconifyMessage = true;
            trayIcon.displayMessage(frame.getTitle(),
                    "The application is still running.",
                    TrayIcon.MessageType.INFO);
        }
    }
}
